package com.xiaotu.spider.project.pageprocessor.list;

import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.xiaotu.common.exception.SpiderException;
import com.xiaotu.common.exception.SpiderExceptionCode;
import com.xiaotu.common.util.Constants;
import com.xiaotu.common.util.DateUtils;
import com.xiaotu.common.util.FileUtil;
import com.xiaotu.common.util.HttpUtils;
import com.xiaotu.common.util.PageUtils;
import com.xiaotu.common.util.PropertiesUtil;
import com.xiaotu.common.util.RegexUtils;
import com.xiaotu.common.util.SepratorUtil;
import com.xiaotu.spider.AUrlPageProcessor;

import us.codecraft.webmagic.Page;
import us.codecraft.webmagic.selector.Html;

/**
 * @类名 SohuListPageProcessor
 * @日期 2017年8月9日
 * @作者 王艳龙
 * @功能 搜狐网站2015-2017热播数据爬取
 */

@Component("SohuListPageProcessor")
@Scope("prototype")
public class SohuListPageProcessor extends AUrlPageProcessor{
	
	private static String [] YEARS = new String[3];//最近三年热播
	
	private static String BASE_URL = "http://so.tv.sohu.com/list_p1100_p2_p3_p4%s_p5_p6_p7_p8_p9_p10_p11_p12_p13.html";
	
	static {
		String[] recentYears = DateUtils.getRecentYears(3);
		for(int i = 0;i<recentYears.length;i++){
			YEARS[i] = String.format(BASE_URL, recentYears[i]);
		}
	}
	
	private String fileName; //存放文件路径
	private String fileName2; //存放文件路径
	@Override
	protected String[] getStartRequestUrls()
	{
		return YEARS;
	}
	
	 @Override
	    public void initRunParams(Map<String, Object> map)
	    {
	        if (map.get("fileName") == null)
	            throw new SpiderException(
	                    SpiderExceptionCode.PageProcessorParameterErrorException);
	        fileName = map.get("fileName") + StringUtils.EMPTY;
	        
	        if (map.get("fileName2") == null)
	            throw new SpiderException(
	                    SpiderExceptionCode.PageProcessorParameterErrorException);
	        fileName2 = map.get("fileName2") + StringUtils.EMPTY;
	    }
	
	@Override
	public String getPageDataType(Page page){
		String url = page.getUrl().toString();
        if (url.contains("http://so.tv.sohu.com/list")){
        	 return Constants.PageDataType.SEARCH_LIST;
        }else if(url.contains("http://tv.sohu.com/item")){
        	 return Constants.PageDataType.TV_RECORD;
        }else if(url.contains("http://film.sohu.com")){
        	 return Constants.PageDataType.TV_PRO_COMMENT;
        }else{
        	 return Constants.PageDataType.SEARCH_LIST;
        }
        
	}
	
	@Override
	public void process(Page page){
		Map<String, Object> tvMap = page.getRequest().getExtras();
		switch (this.getPageDataType(page)){
            case Constants.PageDataType.SEARCH_LIST:
                this.searchProcess(page);
                break;
            case Constants.PageDataType.TV_RECORD:
            	this.getPlayCount(page, tvMap);
            	this.detailsProcess(page,tvMap);
            	break;
            case Constants.PageDataType.TV_PRO_COMMENT:
                this.detailsPlayProcess(page,tvMap);
                break;
            default:
                break;
	     }
	}
	
	public void searchProcess(Page page){
		Map<String, Object> tvMap = page.getRequest().getExtras();
		List<String> divList = page.getHtml()
				.xpath("//div[@class='column-bd cfix']/ul[@class='st-list cfix']/li")
				.all();
		if (divList == null || divList.isEmpty())
			throw new SpiderException(
					SpiderExceptionCode.DataInvalideException);
		for (String divStr : divList){
			Html divObj = new Html(divStr);
			String links =divObj.xpath("//strong/a/@href").get();
			String playCount =divObj.xpath("//a[@class='acount l']/@title").get();
			String movieTime =divObj.xpath("//p[@class='col3a lh-area']/a/@title").get();
			tvMap.put("playCount", playCount);
			tvMap.put("movieTime", movieTime);
			tvMap.put("linkUrl", links);
            PageUtils.addTargetRequest(page, links, page.getRequest().getExtras());
		}
		
		String current = page.getHtml()
				.xpath("//div[@class='ssPages area']/span/text()").get();
		if (StringUtils.isNotEmpty(current))
		{
			current = RegexUtils.regexSearch(RegexUtils.REGEX_INTEGER, current);
			if (StringUtils.isNotEmpty(current))
			{
				if (PropertiesUtil.getPropertyByInt(
						Constants.SpiderConfigKey.HOTTV_PAGE_SIZE) > Integer
								.parseInt(current))
					PageUtils.addTargetRequest(page,
							page.getHtml()
									.xpath("//div[@class='ssPages area']/a[@title='下一页']/@href")
									.get(),
							page.getRequest().getExtras());
			}
		}
	}
	
	//获取点击播放量
	public void getPlayCount(Page page,Map<String,Object> tvMap){
		String scrType =page.getHtml().toString();
		List<String> playIds = getSrings(scrType, Pattern.quote("var playlistId=") +
                "(.*?)" + Pattern.quote("var o_playlistId="));
		for (String playId : playIds) {
			playId =playId.replace("\"", "").replace(";", "").trim();
			String ckCount = HttpUtils.httpGetJSONP("http://count.vrs.sohu.com/count/query_Album.action?albumId="+playId+"&_=1502421366268");
			if(StringUtils.isNotEmpty(ckCount)){
				ckCount =ckCount.replace("var count=", "").replace(";", "");
				tvMap.put("ckCount", ckCount);
			}
			String movieScores =HttpUtils.httpGetJSONP("http://vote.biz.itc.cn/query/score.json?callback=jQuery17204005132173008956_1502434199431&albumId="+playId+"&_=1502434199519");
			if(StringUtils.isNotEmpty(movieScores)){
				String movieScore=movieScores.substring(movieScores.indexOf("score\":\"")+8,movieScores.indexOf("\",\"count"));
				tvMap.put("movieScore", movieScore);
			}
		}
		
	}
	
	//电影详情页
	public void detailsProcess(Page page,Map<String, Object> tvMap){
		StringBuffer buffer = new StringBuffer();
		//网大名称
		String tvName = page.getHtml()
				.xpath("//div[@class='movie-name area rel cfix']/h2/text()").get();
		if(StringUtils.isNotEmpty(tvName)){
			tvName = tvName.replace("电影：", "");
			buffer.append(tvName);
		}
		List<String> movieList =page.getHtml().xpath("//ul[@class='cfix mB20']/li").all();
		for (String str : movieList) {
			Html htmlStr =new Html(str);
			String spanType = htmlStr.xpath("//li/span/text()").get();
			if(spanType.contains("片长")){
				String movieTimeLen = spanType.replace("片长：", "").trim();
				buffer.append(SepratorUtil.SEP_PIPE+movieTimeLen);
			}else if(spanType.contains("上映时间")){
				String movieDate =spanType.replace("上映时间：", "").trim();
				buffer.append(SepratorUtil.SEP_PIPE+movieDate);
				buffer.append(SepratorUtil.SEP_PIPE+tvMap.get("movieTime"));
			}else if(spanType.contains("地区")){
				List<String> movieAreas =htmlStr.xpath("//li/a/text()").all();
				if(movieAreas.size()>0){
					StringBuffer sub = new StringBuffer();
					for (String areas : movieAreas) {
						if(StringUtils.isNotEmpty(areas)){
							if(movieAreas.size()>1){
								sub.append(areas+SepratorUtil.SEP_SPACE_EN);
							}else{
								sub.append(areas);
							}
						}
					}
					String movieCounty =sub.toString(); 
					buffer.append(SepratorUtil.SEP_PIPE+movieCounty);
				}
			}else if(spanType.contains("类型")){
					List<String> movieTypes =htmlStr.xpath("//li/a/text()").all();
					if(movieTypes.size()>0){
					StringBuffer sub = new StringBuffer();
					for (String types : movieTypes) {
						if(StringUtils.isNotEmpty(types)){
							if(movieTypes.size()>1){
								sub.append(types+SepratorUtil.SEP_SPACE_EN);
							}else{
								sub.append(types);
							}
						}
					}
					String movieTyp =sub.toString(); 
					buffer.append(SepratorUtil.SEP_PIPE+movieTyp);
				}
			}
		}
		
		//累计点播量
		String playCount =(String) tvMap.get("ckCount");
		playCount = playCount.trim();
		buffer.append(SepratorUtil.SEP_PIPE+playCount);
		
		//评分
		String movieScore =(String) tvMap.get("movieScore");
		buffer.append(SepratorUtil.SEP_PIPE+movieScore);
		//介绍
		String moviePresent = page.getHtml().xpath("//div[@class='movieCont mod']/p/span[@class='full_intro']/text()").get();
		buffer.append(SepratorUtil.SEP_PIPE+moviePresent);
		
		//网址
		buffer.append(SepratorUtil.SEP_PIPE+tvMap.get("linkUrl"));
		
		//输出csv文件
		FileUtil.writeFile(fileName, buffer.toString()
	                + SepratorUtil.LINE_SEPRATOR);
	}
	
	//电影详情播放页
	public void detailsPlayProcess(Page page,Map<String, Object> tvMap){
		String ulType =page.getHtml().xpath("//div[@class='mt movie-k']").get();
		StringBuffer buffer = new StringBuffer();
		String tvName = page.getHtml()
				.xpath("//div[@class='movie-t']/h3/text()").get();
		buffer.append(tvName);
		
		List<String> movieList =page.getHtml().xpath("//div[@class='mt movie-k']/p/span").all();
		for (String movieStr : movieList) {
			Html htmlStr = new Html(movieStr);
			String spanType =htmlStr.xpath("//span/text()").get();
			
			if(spanType.contains("时长")){
				String movieTimeLen = htmlStr.xpath("//span[@class='one-item']/text()").get();
				movieTimeLen = movieTimeLen.replace("时长：", "").trim();
				buffer.append(SepratorUtil.SEP_PIPE+movieTimeLen);
			}else if(spanType.contains("年份")){
				String movieDate = htmlStr.xpath("//span[@class='one-item']/em/text()").get();
				movieDate =movieDate.trim();
				buffer.append(SepratorUtil.SEP_PIPE+movieDate);
				buffer.append(SepratorUtil.SEP_PIPE+tvMap.get("movieTime"));
			}else if(spanType.contains("地区")){
				StringBuffer sub = new StringBuffer();
				List<String> movieTypes = getSrings(ulType, Pattern.quote("<span class=\"one-item\">类型：") +
                        "(.*?)" + Pattern.quote("</span>"));
				if(movieTypes.size()>0){
					for (String movieTypeStr : movieTypes) {
						String movieType = movieTypeStr.replace("<em>", "").replace("</em>", "");
						if(movieTypes.size()>1){
							sub.append(movieType+SepratorUtil.SEP_SPACE_EN);
						}else{
							sub.append(movieType);
						}
					}
				}
				String movieType =sub.toString();
				buffer.append(SepratorUtil.SEP_PIPE+movieType);
			}else if(spanType.contains("类型")){
				List<String> movieAreas = getSrings(ulType, Pattern.quote("<span class=\"one-item\">地区：") +
                        "(.*?)" + Pattern.quote("</span>"));
				if(movieAreas.size()>0){
					for (String movieArea : movieAreas) {
						buffer.append(SepratorUtil.SEP_PIPE+movieArea);
					}
				}
			}
		}
		//累计点播量
		String playCount =(String) tvMap.get("playCount");
		playCount =playCount.trim();
		buffer.append(SepratorUtil.SEP_PIPE+playCount);
		//评分
		String movieScore =page.getHtml().xpath("//span[@class='movie_score']/text()").get();
		buffer.append(SepratorUtil.SEP_PIPE+movieScore);
		//剧情
		String moviePresent = page.getHtml().xpath("//div[@class='movie_info_wrap']/p[@class='all_info']/text()").get();
		buffer.append(SepratorUtil.SEP_PIPE+moviePresent);
		//网址
		buffer.append(SepratorUtil.SEP_PIPE+tvMap.get("linkUrl"));
		//输出csv文件
				FileUtil.writeFile(fileName2, buffer.toString()
			                + SepratorUtil.LINE_SEPRATOR);
		
	}
	
	 /**
     * 获取多个目标字符串
     */
    public static List<String> getSrings(String input, String regex)
    {
        List<String> result = new LinkedList<String>();
        Pattern pat = Pattern.compile(regex, Pattern.DOTALL);
        Matcher mat = pat.matcher(input);
        while (mat.find())
        {
            result.add(mat.group(1));
        }
        return result;
    }
	
	@Override
	protected String getSpiderType()
	{
		return "SohuList";
	}
}
